#define LOG_TAG    "user_uart"

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#include "project_common.h"


#define UART_PATH               "/dev/ttyS1"
#define UART_BAUD_RATE          (B115200)
#define UART_BUF_SIZE           (2*1024)

static int tty_fd;

/**
* @brief 初始化串口设备
* @param[in] tty_path:tty设备文件的路径
* @param[in] baudrate:波特率，类似B9600，B115200之类的格式
*/
static int user_uart_dev_init(const char *tty_path, speed_t baudrate)
{
    struct termios old_opt,opt;
    tty_fd = open(tty_path, O_RDWR | O_NOCTTY | O_NDELAY);
    
    if (0 > tty_fd) {
        fprintf(stderr, "open error: %s: %s\n", tty_path, strerror(errno));
        return -1;
    }
    // 获取串口参数opt
    if (tcgetattr(tty_fd, &old_opt) < 0) {
        fprintf(stderr, "get opt error: %s: %s\n", tty_path, strerror(errno));
        close(tty_fd);
        return -1;
    };

    memcpy(&opt, &old_opt,sizeof(struct termios));
    // 设置为原始模式
    cfmakeraw(&opt);
    //设置串口输出波特率
    cfsetospeed(&opt, baudrate);
    //设置串口输入波特率
    cfsetispeed(&opt, baudrate);
    //设置数据位数
    opt.c_cflag &= ~CSIZE;
    opt.c_cflag |= CS8;
    //校验位
    opt.c_cflag &= ~PARENB;
    opt.c_iflag &= ~INPCK;
    //设置停止位
    opt.c_cflag &= ~CSTOPB;
    //是能接收
    opt.c_cflag |= CREAD;//CLOCAL | CREAD;
    // 不使用数据流控制
    //opt.c_cflag |= CRTSCTS;
    //opt.c_cflag &= ~CRTSCTS;

    opt.c_cc[VTIME] = 0;//非阻塞模式
    opt.c_cc[VMIN] = 0;

    /* 清空缓冲区 */
    if (0 > tcflush(tty_fd, TCIOFLUSH)) {
        fprintf(stderr, "tcflush error: %s\n", strerror(errno));
        close(tty_fd);
        return -1;
    }

    /* 写入配置、使配置生效 */
    if (0 > tcsetattr(tty_fd, TCSANOW, &opt)) {
        fprintf(stderr, "tcsetattr error: %s\n", strerror(errno));
        close(tty_fd);
        return -1;
    }
    return 0;
}


//user uart模块的任务
static void *user_uart_task(void *arg)
{
    user_uart_dev_init(UART_PATH, UART_BAUD_RATE);

    // Configure a temporary buffer for the incoming data
    uint8_t *data = (uint8_t *) malloc(UART_BUF_SIZE);

    //注册socket模块的回调函数
    app_socket_regist_cb(at_cmd_is_in_pass_mode, at_cmd_set_pass_mode);

    while (1) {
        usleep(10*1000);//减少非阻塞的read()的调用频率
        // Read data from the UART
        int len = read(tty_fd, data, UART_BUF_SIZE-1);
        if (len) {
            data[len] = '\0';
            log_i("Recv str: %s", (char *) data);
        }
        if (len > 0) {
            if (!at_cmd_is_in_pass_mode()) {//AT mode
                user_uart_send(data, len);//echo
                at_cmd_recv_hand((char*)data, len);
            }
            else {//透传
                // 通过socket client发送数据到server
                app_socket_client_send_data(data, len);
            }
        }
    }
    pthread_exit(NULL);
}
//user uart模块的初始化
void user_uart_init(void)
{
    pthread_t uart_tid;
    pthread_create(&uart_tid, NULL, user_uart_task, NULL);
}
//通过user uart将普通数据发送出去
void user_uart_send(uint8_t *data, uint16_t len)
{
    write(tty_fd, data, len);
}
//通过user uart将格式化字符发送出去
void user_uart_print(char * format, ...)
{
    char buffer[256];
    int len;
    va_list args;
    va_start(args, format);
    len = vsnprintf(buffer, 255, format, args);
    if (len >= 0) {
        user_uart_send((uint8_t*)buffer, len);
    }
    va_end (args);
}
